//
//  TableViewModel.swift
//  Automobile
//
//  Created by erkebulan elzhan on 7/22/20.
//  Copyright © 2020 erkebulan elzhan. All rights reserved.
//

import UIKit

typealias SegmentedCellConfigurator = TableCellConfigurator<SegmentedCell, Segmented>
typealias ParametersCellConfigurator = TableCellConfigurator<ParametersCell, CarFilterModel>
typealias PostCellConfigurator = TableCellConfigurator<PostCell, PostModel?>
typealias ButtonsCellConfigurator = TableCellConfigurator<ButtonsCell, Filter?>

final class ResultsViewModel {
    
    private struct Inputs {
        static let shared = Inputs()
        var region = Input(type: "region",
                           value: "Алматинская область",
                           placeholder: "Область")
    }
    
    var delegate: ViewModelProtocol!
    
    var items: [CellConfigurator] = [ SegmentedCellConfigurator(item: Segmented(segments: TransportFeature.allCases.map { $0.rawValue }))
    ]
    
    var posts: [Post]!
    
    var filter: Filter! = Filter(filterGeneral: Filter.FilterGeneral(), filterCar: Filter.FilterCar(), filterOptional: Filter.FilterOptional(), filterChecks: Filter.FilterChecks(), carDetailedType: nil) {
        didSet {
            self.loadPosts()
        }
    }
    
    var nextPage: String?
    
    private var filterHandler: FilterManager = FilterManager()
}

// MARK: - Methods

extension ResultsViewModel {
    
    func initFilter () {
        self.addMarkModel(carFilter: filter.filterCar.carParameters ?? CarFilter(models: []))
        items.append(ButtonsCellConfigurator(item: filter))
    }
    
    func updateMarkModel (carFilter: CarFilter) {
        let carFilterModel = CarFilterModel(carFilter: carFilter)
        if items.count >= 2 {
            items[1] = ParametersCellConfigurator(item: carFilterModel)
        }
    }
    
    func clearParameter (cellIndex: Int, parameterIndex: Int) -> CarFilter {
        var carFilter = (items[cellIndex] as! ParametersCellConfigurator).item.carFilter
        if (parameterIndex == 0) {
            carFilter.marka = nil
            carFilter.models = []
        } else if parameterIndex == 1{
            carFilter.models = []
        } else {
            for (i,_) in carFilter.models.enumerated() {
                carFilter.models[i].generation = []
            }
        }
        (items[cellIndex] as! ParametersCellConfigurator).item.carFilter = carFilter
        return carFilter
    }
    
    private func addMarkModel (carFilter: CarFilter) {
        let carFilterModel = CarFilterModel(carFilter: carFilter)
        items.append(ParametersCellConfigurator(item: carFilterModel))
    }
    
    private func putNewPosts (posts: [Post]) {
        var kf = 0
        for (i, cell) in items.enumerated() {
            if (cell is PostCellConfigurator) {
                items.remove(at: i - kf)
                kf+=1
            }
        }
        for post in posts {
            items.append(PostCellConfigurator(item: PostModel(post: post)))
        }
        delegate!.updatePosts()
    }
}


// MARK: - Network

extension ResultsViewModel {
    
    func loadPosts (paginate: Bool = false) {
        delegate.updateSpinner(showSpinner: true)
        let paginationReq = paginate ? URLRequest(url: URL(string: nextPage!)!) : nil
        
        filterHandler.getPosts(filter: filter, request: paginationReq) { (result) in
            self.delegate.updateSpinner(showSpinner: false)
            switch result {
            case .failure(let err):
                self.delegate.didHappenError(error: err)
            case .success(let response):
                self.posts = paginate ? self.posts + response.results : response.results
                self.putNewPosts(posts: self.posts)
            }
        }
    }
    
    func updateFavorite (index: Int) {
        let isRemove = posts[index].isLiked
        
        Backend().addToFavorites(advertID: posts[index].id, isRemove: isRemove) { (isSuccess, errorMessage) in
            if isSuccess {
                self.posts[index].isLiked.toggle()
            } else {
                self.delegate.didHappenError(error: .parameter(errorMessage!))
            }
        }
    }
}
